
use strict;
use warnings;
use utf8;
use Me2day;
use XML::Simple;
use LWP::Simple;
use Data::Dumper;
use Encode;
use constant KEY => "74589a73e765e8a2df0fa030c38c28ad";
use constant PATH => $ENV{HOME}."/.me2day/";

use YAML::Syck;

my ($me2day, $id, $pass);

init();

my $friends_info = get_friendsinfo();

get_posts($friends_info);
get_comments();
# comment pubDate 등록
# comment pubDate 와 Latests update 를 비교

BEGIN {
    binmode(STDOUT, ":utf8");
}

sub get_posts {
    my $data = shift;
    while(my ($key, $row) = each %{ $data }) {
	next unless $row->{notify}; #
	my $from = $row->{updated};
	$from =~ s/[TZ:-]//g;
	my $res = $me2day->get_latests(username => $key);
	if ($res->status_line =~ /200/) {
	    sleep 1;
	    my $post = XMLin($res->content);
	    fetchPost($post, $from);
	}
    }
    create_friends_info($friends_info);
}

sub get_comments {
    my $res = $me2day->track_comments( scope => "to_me", count => 10 );
    if ($res->status_line =~ /200/) {
	my $data = XMLin($res->content);
	my $date;
	foreach my $key (@{ $data->{commentToMe} }) {
	    my $temp_date = $key->{comment}->{pubDate};
	    $temp_date =~ s/[TZ:-]//g;
	    my $id = $key->{comment}->{author}->{id};
	    my $nick = $key->{comment}->{author}->{nickname};
	    my $body = $key->{comment}->{body};
	    my $image = get_info($id, "image") || PATH. "default.png";
	    system("growlnotify -t \'Comment:".$nick.": $temp_date\' -m \'".$body."\' --image \'".$image."\'");
	    # Set info about me
	    sleep 1;
	}
	# create_info about me
    }
}

sub fetchPost {
    my ($post, $from) = @_;

    foreach my $key (@{ $post->{post} }) {
	my $pubdate = $key->{pubDate};
	$pubdate =~ s/[TZ:-]//g;
	last if $pubdate <= $from;
	my $dates = $key->{pubDate};
	$dates =~ s/[TZ]/ /g;
	my $id = $key->{author}->{id};
	my $body = $key->{body};
	system("growlnotify -t \'".Encode::decode("utf8", get_info($id, "nickname")).": $dates\' -m \'".$body."\' --image \'".get_info($id, "image")."\'");
	set_info($id, "updated", $key->{pubDate});
	sleep 1;
    }
}

sub set_info {
    my ($id, $key, $value) = @_;

    $friends_info->{$id}->{$key} = $value;
}

sub get_info {
    my ($id, $key) = @_;
    $friends_info = $friends_info || get_friendsinfo();
    $friends_info->{$id}->{$key};
}

sub get_friendsinfo {
    get_friends() unless -f PATH.".friends";
    my $data = LoadFile(PATH.".friends");
    $data;
}

sub create_friends_info {
    my $data = shift;
    return unless $data;
    
    open my $fh,">", PATH.".friends";
    print $fh Dump($data);
    close $fh;
}

sub get_friends {
    my $user = shift;
    my %args;
    $args{username} = $user if $user;
    my $res = $me2day->get_friends(%args);
    if ($res->status_line =~ /200/) {
	my $data = XMLin($res->content);
	my $dataset;
	while(my ($key, $row) = each %{ $data->{person} }) {
	    my $image = save_image($key, $row->{face});
	    $dataset->{$key} = { 
		nickname => $row->{nickname},
		friends => $row->{friendsCount},
		notify => 1, 
		updated => $row->{updated},
		image => $image,
	    };
	}
	create_friends_info($dataset) if $dataset;
    }
}

sub save_image {
    my ($id, $image) = @_;

    my $content = get($image);

    my $path = PATH."$id.png";
    open my $w, ">", $path;
    print $w $content;
    close $w;
    $path;
}

sub _connect {
    my ($username, $userkey) = @_;

    $me2day = Me2day->new( username => $username, user_key => $userkey, app_key => KEY );
    my $test = $me2day->noop;
    
    if ($test->status_line =~ /200/) {
	return ($me2day->{username}, $me2day->{password})
    } else {
	return;
    }
}

sub init {
    open my $fh, "<", PATH.".me2day_info" or return create_info();
    my ($username, $userkey) = split("\t", (join "", <$fh>));
    ($id, $pass) = _connect($username, $userkey);
    unless ($id && $pass) {
	print STDERR "인증에 실패했습니다. 다시금 인증정보를 입력해주세요.\n";
	print STDERR "-----------------------------------------------------\n";
	return create_info();
    }

}

sub create_info {
    print "Me2day ID 를 입력해주세요 : ";
    my $username = <STDIN>;
    chomp $username;
    print "\"사용자키\"를 입력해주세요 : ";
    my $userkey = <STDIN>;
    chomp $userkey;
    ($id, $pass) = _connect($username, $userkey);
    if ($id && $pass) {
	mkdir $ENV{HOME}."/".".me2day";
	open my $fh, ">", PATH.".me2day_info";
	print $fh $username."\t".$userkey;
    } else {
	print STDERR "인증에 실패했습니다. Me2day ID와 사용자키를 확인하신 후 다시 입력해주세요\n";
	print STDERR "-------------------------------------------------------------------------\n";
	create_info();
    }
}

